#include "read_boy_base.h"
#include "read_boy_confg.h"
#include "read_boy.h"

void DelayMs(uint32_t xms)
{
	sleep_ms(xms);
}
void Delayus(uint32_t xus)
{
    sleep_us(xus );
}
void DigitalWrite(uint16_t Pin, uint8_t Value)
{
	gpio_put(Pin, Value);
}
uint8_t Digital_Read(uint16_t Pin)
{
	return gpio_get(Pin);
}
#define DigitalRead_BUSY   Digital_Read(EPD_BUSY_PIN)


void readboyEpdBase_GPIOInit(void)
{
		   		
	gpio_init(EPD_CLK_PIN);
    gpio_set_dir(EPD_CLK_PIN, GPIO_OUT);
	
		gpio_init(EPD_MOSI_PIN);
    gpio_set_dir(EPD_MOSI_PIN, GPIO_OUT);
	
		gpio_init(EPD_RST_PIN);
    gpio_set_dir(EPD_RST_PIN, GPIO_OUT);
	
		gpio_init(EPD_DC_PIN);
    gpio_set_dir(EPD_DC_PIN, GPIO_OUT);
	
		gpio_init(EPD_CS_PIN);
    gpio_set_dir(EPD_CS_PIN, GPIO_OUT);
	
		gpio_init(EPD_BUSY_PIN);
    gpio_set_dir(EPD_BUSY_PIN, GPIO_IN);
		gpio_set_pulls(EPD_BUSY_PIN,1, 0);   
    //gpio_set_pulls(EPD_BUSY_PIN,0, 1); 


		DigitalWrite(EPD_CS_PIN, 1);
		
		
    gpio_set_function(EPD_CLK_PIN, GPIO_FUNC_SPI);
    gpio_set_function(EPD_MOSI_PIN, GPIO_FUNC_SPI);
		spi_init(spi0, 4000 * 1000);
	
		
}

void readboyEpdBase_Reset(uint32_t minTime)
{
  
	DigitalWrite(EPD_RST_PIN, LOW);                //module reset
	DelayMs(minTime);
	DigitalWrite(EPD_RST_PIN, HIGH);
	DelayMs(minTime);
}

void readboyEpdBase_BeginTransfer(){
 
    DigitalWrite(EPD_CS_PIN, LOW);
    
}

void readboyEpdBase_EndTransfer(){
 
    DigitalWrite(EPD_CS_PIN, HIGH);
   
}

void SpiTransfer(uint8_t Value){
    spi_write_blocking(spi0, &Value, 1);
		
}

void readboyEpdBase_boy_epdCmd(unsigned char command)
{

	DigitalWrite(EPD_DC_PIN, LOW);
	SpiTransfer(command);
	DigitalWrite(EPD_DC_PIN, HIGH);
}

void readboyEpdBase_boy_epdParam(unsigned char data)
{

	SpiTransfer(data);
}

int  drv_width() {
    return my_drv_base.epdWidth;//get_my_drv_base_epdWidth();
}
int  drv_height() {
    return my_drv_base.epdHeight;//get_my_drv_base_epdHeight();
}

void readboyEpdBase_SetMemory() {
    readboyEpdBase_boy_epdCmd(0x44);
    /* x point must be the multiple of 8 or the last 3 bits will be ignored */
    readboyEpdBase_boy_epdParam(0);
    readboyEpdBase_boy_epdParam(((drv_width()-1) >> 3) & 0xFF);
    readboyEpdBase_boy_epdCmd(0x45);
    readboyEpdBase_boy_epdParam(0);
    readboyEpdBase_boy_epdParam(0);
    readboyEpdBase_boy_epdParam((drv_height()-1) & 0xFF);
    readboyEpdBase_boy_epdParam(((drv_height()-1) >> 8) & 0xFF);
    
    readboyEpdBase_boy_epdCmd(0x4E);
    /* x point must be the multiple of 8 or the last 3 bits will be ignored */
    readboyEpdBase_boy_epdParam(0);
    readboyEpdBase_boy_epdCmd(0x4F);
    readboyEpdBase_boy_epdParam(0);
    readboyEpdBase_boy_epdParam(0);
}



void readboyEpdBase_boy_epdBusy(int32_t maxt) {

    
  int32_t mls = maxt;//millis();  
  if(maxt<0){      //HIGH: idle, LOW: busy
      while((DigitalRead_BUSY==0) && mls){
          DelayMs(1);
          mls++;
      }
  }
  else{      //LOW: idle, HIGH: busy
      while((DigitalRead_BUSY==1) && mls){
        
          DelayMs(1);
          mls--;
      }
  }

}


//void readboyEpdBase_drv_draw16grey(LGFX_Sprite &sprbase,LGFX_Sprite &spr,int32_t x,int32_t y,
//  int32_t fw0, int32_t fh){
//  //Serial.println("drv_draw16grey fx");
//  if(!fw0) fw0=spr.width();
//  if(!fh)  fh=spr.height();
//  if((!fw0) || (!fh)) return;
//  int32_t fw=(fw0>0?std::min(fw0,sprbase.width()):-fw0);
//  fw0=std::abs(fw0); //无视缩放优化, 0~3:常规的三种渲染模式, 4~7: 无视缩放优化
//  readBuff = new uint16_t[spr.width()];
//  if(_quality&2){
//    floyd_tab[0] = new int16_t [fw];
//    floyd_tab[1] = new int16_t [fw];
//  }
//  writeBuff = new uint8_t[(fw+7)>>3];
//  sprbase.fillRect(x,y,fw,fh,1);
//  bool negativeOrder=(drv_supportGreyscaling()==-16);
//  drv_fullpart(0);
//  //_display((const uint8_t*)sprbase.getBuffer()); //先对区域慢刷白屏确保颜色正确
//  drv_dispWriter(FILL_WHITE);
//  drv_fullpart(1);
//  for(uint_fast8_t k=1;k<16;k++){ //亮度为15的不用绘制,因为本来就是白色
//    if(_quality&2) for(int j=0;j<fw;j++){ floyd_tab[0][j] = 0; floyd_tab[1][j] = 0; }
//    for(int i=y;i<(int32_t)fh+y;i++){
//      uint_fast8_t buff8bit=0;
//      spr.readRect(0,(i-y)*spr.height()/fh,spr.width(),1,readBuff);
//      for(int32_t j=0;j<fw;j++){
//        //for(uint_fast8_t b=0;b<8;b++){
//        uint_fast8_t cg=0;
//        if(_quality&2){
//          int gv=greysc(readBuff[j*spr.width()/fw0]);
//          int32_t fd = floyd_tab[i&1][j]+((gv<<8)|gv);
//          while(fd>=0x800) { 
//            cg++;
//            if(fd>=0) fd -= 0x1000;
//          }
//          if(fd<0) fd++;
//          if(j!=fw-1) { floyd_tab[i&1]   [j+1] += (fd*7)>>4; }
//          if(j)       { floyd_tab[!(i&1)][j-1] += (fd*3)>>4; }
//                      { floyd_tab[!(i&1)][j  ] += (fd*5)>>4; }
//          if(j!=fw-1) { floyd_tab[!(i&1)][j+1] += (fd  )>>4; }
//        }
//        else{ cg=greysc(readBuff[j*spr.width()/fw0])>>4; }
//          //uint_fast8_t cg=greysc(readBuff[j*spr.width()/fw0])>>4;
//          if(negativeOrder)
//            buff8bit |= (cg<k)<<((~j)&7);
//          else{
//            if(cg<15) //白色不考虑
//              buff8bit |= (cg>=((~k)&15))<<((~j)&7);
//          }
//          if((j&7)==7 || j==((int32_t)fw-1)){
//            writeBuff[j>>3]=buff8bit^0xff;
//            buff8bit=0;
//          }
//        //}
//        //sprbase.drawPixel(x+j,i,(greysc(readBuff[j*spr.width()/fw0])/16)==(15-k));
//      }
//      if(_quality&2) for(int floi=0;floi<fw;floi++) floyd_tab[i&1][floi]=0;
//      sprbase.drawBitmap(x,i,writeBuff,fw,1,1,0);
//    }
//    drv_draw16grey_step((const uint8_t*)sprbase.getBuffer(),k); //使用灰度显示函数
//  }
//  delete []readBuff;
//  delete []writeBuff;
//  if(_quality&2){
//    delete [] floyd_tab[0] ;
//    delete [] floyd_tab[1] ;
//  }
//} 


















